package edu.purdue.cs.aggr;

import java.util.HashMap;
import java.util.Map;

import edu.purdue.cs.aggr.message.EventMessageBuilder;
import edu.purdue.cs.aggr.message.Message;
import edu.purdue.cs.aggr.message.EventNotificationMessage.Event;

public class VertexManager extends Node
{
  private Map<String, Vertex> nodes = new HashMap<String, Vertex>();

  public VertexManager(String IP, int port, String controllerId)
  {
    super(IP, port, true);
    this.controllerId = controllerId;
    
    // create the initial node in this manager
    Vertex initial = new Vertex(IP, port, this);
    initial.setControllerId(this.getControllerId());
    addNode(initial);
  }

  public void addNode(Vertex node)
  {
    System.out.println("Manager " + getId() + " added vertex: " + node.getId());
    nodes.put(node.getId(), node);
    node.setManager(this);
  }

  public void sendMessage(Message message)
  {
    // check if dest is local, if not send it to proper place
    if (nodes.containsKey(message.getDestination())) {
      // we have this node
      try {
        System.out.println("Transmitting message to " + message.getDestination() + " locally (from " + message.getSender() + ")");
        listener.handleMessage(message);
      }
      catch (AggrException e) {
        e.printStackTrace();
      }
    }
    else {
      /*
       * otherwise, the original address is valid; we only combine nodes in such a way so that a
       * group of nodes contains the children of the original node at that address; this node's
       * parent is either unchanged, or the node itself was a child of that parent and was moved
       * into the parent node
       */
      sender.sendMessage(message, message.getDestination());
    }
  }

  @Override
  public void run()
  {
    // start the vertex that shares an ID with this manager
    new Thread(nodes.get(getId())).run();
  }

  public Vertex getVertex(String destination)
  {
    //System.out.println("Getting " + destination + " on " + getId());
    return nodes.get(destination);
  }

}
